package com.lsu.app.controller.Student;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lsu.app.bean.*;
import com.lsu.app.config.target.RequestRoles;
import com.lsu.app.service.*;
import com.lsu.app.tool.AESUtil;
import com.lsu.app.tool.R;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @author hjj
 * @date 2023/10/16 18:56
 */
@RestController
@Slf4j
@CrossOrigin
@RequestMapping("/detes")
public class DetectionController {
    @Value("${web.upload-path}")
    private String uploadPath;
    @Autowired
    private HttpServletRequest request;
    private final ClickDateService clickDateService;
    private final CourseScoreService scoreService;
    private final CourseService courseService;
    private final TalkService talkService;
    private final ResourceService resourceService;
    private final CommentService commentService;
    private  final UserTasteService tasteService;
    private final KindService kindService;
    private final PraiseService praiseService;
    private final UserService userService;
    private final CollectService collectService;

    public DetectionController(ClickDateService clickDateService, CourseScoreService scoreService, CourseService courseService, TalkService talkService, ResourceService resourceService, CommentService commentService, UserTasteService tasteService, KindService kindService, PraiseService praiseService, UserService userService, CollectService collectService) {
        this.clickDateService = clickDateService;
        this.scoreService = scoreService;
        this.courseService = courseService;
        this.talkService = talkService;
        this.resourceService = resourceService;
        this.commentService = commentService;
        this.tasteService = tasteService;
        this.kindService = kindService;
        this.praiseService = praiseService;
        this.userService = userService;
        this.collectService = collectService;
    }
    @RequestRoles({"student","teacher"})
    @GetMapping("/search")
    @ApiOperation("s学生模糊查询&分类查询课程")
    public R<Page<Course>> search(
            @ApiParam("当前页")@RequestParam("pageCur") Integer pageCur,
            @ApiParam("页码")@RequestParam("pageSize") Integer pageSize,
            @ApiParam("搜索词")@RequestParam("searchText") String searchText,
            @ApiParam("根据获取的一个或多个课程类型获取课程(用英文逗号隔开)")@RequestParam("typeNames") String typeNames,
            @ApiParam("排序方式[1最新时间，2热度，3综合(默认)]")@RequestParam("sort") Integer sort
    ){
        if(searchText==null){
            return R.err("请勿空查询");
        }
        //字符串查询
        LambdaQueryWrapper<Course> wrapper = new LambdaQueryWrapper<>();
        if(!searchText.equals("")){
            wrapper.like(Course::getCourseName,searchText); //与课程名模糊
            List<Integer> kinds = kindService.getCourseIdsByKindName(searchText);
            if(!kinds.isEmpty()){
                wrapper.or().in(Course::getId,searchText);//与课程分类模糊
            }

        }
        //分类查询
        if(typeNames!=null&&typeNames.length()>0){
            String[] str = typeNames.trim().split(",");
             Set<Integer> kinds = new HashSet<>();
             List<Kind> kindList= kindService.list(new LambdaQueryWrapper<Kind>().in(Kind::getKvValue, (Object[]) str));
            for (Kind kind : kindList) {
                kinds.add(kind.getId());
            }
            if(!kinds.isEmpty()){
                wrapper.in(Course::getId,kinds);
            }
        }
        if(sort==1){//更新时间排序
            wrapper.orderByDesc(Course::getUpdateTime);
        }else if(sort==2){//热度排序
            wrapper.orderByDesc(Course::getHeat);
        }else{//按照优先级排序
            wrapper.orderByDesc(Course::getCreateTime);//先查询到课程名的优先级高
        }
        Page<Course> page = courseService.page(new Page<>(pageCur,pageSize),wrapper);
        page.setRecords(setCourseData(page.getRecords()));
        return R.success(page);
    }

    /**
     * 课程信息赋值
     * @param courseList
     * @return
     */
    public List<Course> setCourseData(List<Course> courseList){
        for (Course course : courseList) {
            course.setTeacherName(courseService.getTeacherNameByTeacherId(course.getTeacherId()));
            course.setCoverImgUrl(resourceService.getCoverImgUrlByCourseId(course.getId()));
            course.setResponds(commentService.getCountByTypeAndLinkId(1,course.getId()));
            course.setKindName(kindService.getValueByCourseId(course.getId()));
            course.setSelfLike(praiseService.getSelfLike(course.getId(),3));
            course.setSelfCollect(collectService.collectCount(course.getId(),2));
            course.setTeacherImgUrl(resourceService.getHeadUrlByUorrIdAndType(course.getTeacherId()));
        }
        return courseList;
    }

    @RequestRoles({"student","teacher"})
    @GetMapping("/recommend")
    @ApiOperation("s课程智能推荐[分页]")
    public R<Page<Course>> getRecommend(
            @ApiParam("当前页")@RequestParam("pageCur") Integer pageCur,
            @ApiParam("页码")@RequestParam("pageSize") Integer pageSize,
            @ApiParam("推荐类型（[0按照最近更新视频排序(默认)],[1根据用户兴趣、收藏],）")@RequestParam("type") Integer type
    ){
        if(type==1){
            Integer userId = (Integer) request.getSession().getAttribute("id");
            //获取用户兴趣对应课程类别id集合
            Set<Integer> kindIds = tasteService.getKindIdsByTasteIds(userId);
            //加入用户收藏课程的类别id集合
            kindIds.addAll(collectService.CourseKindIdsByUserId(userId));
            if(kindIds.isEmpty()){
                Page<Course> page = courseService.page(new Page<>(pageCur,pageSize),new LambdaQueryWrapper<Course>().orderByDesc(Course::getUpdateTime));
                page.setRecords(setCourseData(page.getRecords()));
                return R.success(page);
            }
            //获取按照兴趣、收藏 排好的 课程id 集合
            LambdaQueryWrapper<Kind> wrapper;
            Map<Integer,Integer> map = new HashMap<>();
            for (Integer courseId : courseService.getCourseIds()) {
                wrapper = new LambdaQueryWrapper<Kind>().in(Kind::getKvValueId,kindIds).eq(Kind::getCourseId,courseId);
                int num  = (int) kindService.count(wrapper);
                if(num>0){
                    map.put(courseId,num);
                }
            }
            List<Integer> CourseIds = new ArrayList<>(AESUtil.sortDescend(map).keySet());
            //注入page
            Page<Course> page = new Page<>(pageCur,pageSize,CourseIds.size());
            if(CourseIds.size()!=0){
                List<Course> recodes = new ArrayList<>();
                for(int i=(pageCur-1)*pageSize;i<pageSize*pageCur&&i<CourseIds.size();i++){
                    recodes.add(courseService.getById(CourseIds.get(i)));
                }
                //赋值课程其他信息
                page.setRecords(setCourseData(recodes));
            }
            return R.success(page);
        }else if (type==2){
            return null;
        }else {
            Page<Course> page = courseService.page(new Page<>(pageCur,pageSize),new LambdaQueryWrapper<Course>().orderByDesc(Course::getUpdateTime));
            page.setRecords(setCourseData(page.getRecords()));
            return R.success(page);
        }
    }

    @RequestRoles({"student"})
    @GetMapping("/getVideos")
    @ApiOperation("s获取课程下的所有视频")
    public R<List<Resource>> getVideosByCourseId(
            @ApiParam("利用返回的课程id传入")@RequestParam("id") Integer id
    ){
        if(courseService.getById(id)==null){
            return R.err("课程不存在");
        }
        List<Resource> resources = resourceService.list(new LambdaQueryWrapper<Resource>()
                .eq(Resource::getType,1)
                .eq(Resource::getUorrId,id)
                .orderByAsc(Resource::getEpisodes));
        for (Resource resource : resources) {
            resource.setUrl(resourceService.getVideoUrlByUorrIdAndId(id,resource.getId()));
            resource.setTeacherName(resourceService.getTeacherNameByVideoId(resource.getUorrId()));
            resource.setSelfLike(praiseService.getSelfLike(resource.getId(),4));
        }
        //增加点击量
        courseService.addClickById(id);
        clickDateService.updateClickNumById(id);
        //加入社区
        talkService.stuInsert((Integer) request.getSession().getAttribute("id"),id);
        return R.success(resources);
    }

    @RequestRoles({"student"})
    @GetMapping("/courseKinds")
    @ApiOperation("d获取所有课程类别")
    public R<List<String>> getKinds(){
        return R.success(kindService.getAllKindValue());
    }

    @RequestRoles({"student"})
    @GetMapping("/searchTeachers")
    @ApiOperation("s根据教师昵称或账号查询教师")
    public R<Page<User>> getTeachers(
            @ApiParam("当前页")@RequestParam("pageCur") Integer pageCur,
            @ApiParam("页码")@RequestParam("pageSize") Integer pageSize,
            @ApiParam("根据获取的一个或多个课程类型获取课程")@RequestParam("searchName") String searchName
    ){
        if(searchName==null||searchName.equals("")){
            return R.err("请勿空查询");
        }
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername,searchName)
                .or().like(User::getName,searchName)
                .or().like(User::getName,searchName+"%")
                .or().like(User::getName,"%"+searchName+"%");
        wrapper.eq(User::getState,1);
        wrapper.orderBy(true,false,User::getUsername, User::getName);
        Page<User> users = userService.page(new Page<>(pageCur,pageSize),wrapper);
        for (User user : users.getRecords()) {
            user.setImageUrl(resourceService.getHeadUrlByUorrIdAndType(user.getId()));
            user.setTaste(userService.getTasteById(user.getId()));
            user.setSelfLikeCollect(collectService.collectCount(user.getId(),2));
            user.setFans(collectService.CountByTeacherId(user.getId()));
            user.setSelfLikeCollect(collectService.isCollect(user.getId(), (Integer) request.getSession().getAttribute("id")));
        }
        return R.success(users);
    }



    @RequestRoles({"student"})
    @GetMapping("/searchCourseByTeacher")
    @ApiOperation("s根据教师id查询该教师的所有课程[分页]")
    public R<Page<Course>> searchCourseByTeacher(
            @ApiParam("当前页")@RequestParam("pageCur") Integer pageCur,
            @ApiParam("页码")@RequestParam("pageSize") Integer pageSize,
            @ApiParam("教师id")@RequestParam("teacherId") Integer teacherId
    ){
        LambdaQueryWrapper<Course> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Course::getTeacherId,teacherId);
        Page<Course> page = courseService.page(new Page<>(pageCur,pageSize),wrapper);
        page.setRecords(setCourseData(page.getRecords()));
        return R.success(page);
    }

    @RequestRoles({"student","teacher"})
    @GetMapping("/getCourseScore")
    @ApiOperation("获取课程评分")
    public R<Double> getCourseScore(
        @ApiParam("课程id")@RequestParam("courseId") Integer courseId
    ){
        if(courseService.getById(courseId)==null){
            return R.err("课程不存在");
        }
        return R.success(scoreService.getValScoreByCourseId(courseId));
    }




}
